#include "omelette.hpp"
#include "sim.hpp"
#include "../utils/utils.hpp"
#include <cstring>
#include <cstdint>

int main(int argc, const char *argv[]) {
	uint64_t seed = walltime() * 1e9;

	if (argc < 2)
		fatal("Usage: sim <alg> [-s <seed>] [-brown <prob>] [-badwhite <prob>] [-badbrown <prob>] [-nsamp <num>]");

	const char *alg = argv[1];
	unsigned int nsamp = 32;

	for (int i = 2; i < argc; i++) {
		if (i < argc-1 && strcmp(argv[i], "-s") == 0) {
			char *end = NULL;
			seed = strtoul(argv[++i], &end, 10);
			if (end == argv[i])
				fatal("Invalid seed: %s", argv[i]);

		} else if (i < argc-1 && strcmp(argv[i], "-brown") == 0) {
			char *end = NULL;
			omelette::BrownProb = strtod(argv[++i], &end);
			if (end == argv[i])
				fatal("Invalid brown egg probability: %s", argv[i]);

		} else if (i < argc-1 && strcmp(argv[i], "-badwhite") == 0) {
			char *end = NULL;
			omelette::BadProb[omelette::White] = strtod(argv[++i], &end);
			if (end == argv[i])
				fatal("Invalid bad white egg probability: %s", argv[i]);

		} else if (i < argc-1 && strcmp(argv[i], "-badbrown") == 0) {
			char *end = NULL;
			omelette::BadProb[omelette::Brown] = strtod(argv[++i], &end);
			if (end == argv[i])
				fatal("Invalid bad brown egg probability: %s", argv[i]);
		} else if (i < argc-1 && strcmp(argv[i], "-nsamp") == 0) {
			if (strcmp(alg, "hindsight") != 0)
				fatal("-nsamp only valid for hindsight");
			char *end = NULL;
			nsamp = strtoul(argv[++i], &end, 10);
			if (end == argv[i])
				fatal("Invalid number of samples: %s", argv[i]);
		}
	}
	fprintf(stderr, "seed=%lu\n", (unsigned long) seed);
	dfheader(stdout);

	randgen = Rand(0);
	omelette::State init(seed);

	Planner *planner = NULL;

	if (strcmp(alg, "oracle") == 0)
		planner = new Oracle(init);
	else if (strcmp(alg, "hindsight") == 0)
		planner = new Hindsight(nsamp);
	else if (strcmp(alg, "handmade") == 0)
		planner = new Handmade();

	if (!planner)
		fatal("Unknown algorithm: %s", alg);

	sim(init, planner);
	dfpair(stdout, "seed", "%lu", (unsigned long) seed);
	dfpair(stdout, "brown egg prob", "%g", omelette::BrownProb);
	dfpair(stdout, "bad white egg prob", "%g", omelette::BadProb[omelette::White]);
	dfpair(stdout, "bad brown egg prob", "%g", omelette::BadProb[omelette::Brown]);

	dfpair(stdout, "alg", "%s", alg);

	if (strcmp(alg, "hindsight") == 0)
		dfpair(stdout, "number of samples", "%u", nsamp);

	dffooter(stdout);
}